package cn.dlc.com.config;

import javax.sql.DataSource;

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.alibaba.druid.pool.DruidDataSource;

import cn.dlc.com.config.Config;
import cn.dlc.com.config.ConfigCenter;
import cn.dlc.com.property.ZookeeperProperty;
import tk.mybatis.spring.annotation.MapperScan;

@Configuration
@MapperScan("cn.dlc.com.dao")
@EnableConfigurationProperties(ZookeeperProperty.class)
public class ClientConfig {
	
	/**
	 * 交给bean管理，要用的时候直接获取这个对象，调用获取config对象的方法
	 * @param zk
	 * @return
	 */
	@Bean
	public ConfigCenter configCenter() {
		ConfigCenter configCenter = new ConfigCenter();
		return configCenter;
	}
		
	
	@Bean
	public DataSource dataSource(ZookeeperProperty zk) throws Exception{
		
		DruidDataSource dataSource = new DruidDataSource();
		// 获取配置中心的数据，然后初始化连接池对象。
		ConfigCenter configCenter =  configCenter();
		// 获取数据
		Config config = configCenter.getConfig(zk.getUrl(), zk.getNodePath());
			
		// 初始化配置
		dataSource.setDriverClassName(config.getDriverClass());
		dataSource.setUrl(config.getDbUrl());
		dataSource.setUsername(config.getUsername());
		dataSource.setPassword(config.getPassword());
		// 连接超时时间设置
		dataSource.setMaxWait(3000);
		// 重连1次
		dataSource.setConnectionErrorRetryAttempts(1);
			
		return dataSource;
	}
	
	
	
	// 这个是之前的思路，引以为鉴，
	/*@Bean
	public Config config(ZookeeperProperty zk) throws Exception{
		config = new Config();
		// 创建连接
		System.out.println("zk: " + zk.getUrl());
		
		// 首先创建连接，
		zkClient = new ZooKeeper(zk.getUrl(), 2000, new Watcher() {

			@Override
			public void process(WatchedEvent event) {
				try {
					// 节点数据修改之后，触发这个监听，
					if(event.getType().equals(EventType.NodeDataChanged)) {
						
						// 理论上来说这个地方直接重新加载容器就可以搞定了，但是就是不知道怎么重新加载容器，
						// 下面这个方式仅仅是重新加载当前ClientConfig里面的配置信息，
						// 根本无法修改Controller里面的东西
						
						// 
						
						AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
						ac.register(ClientConfig.class);
						ac.refresh();
						
						// 刷新指定的bean
						DefaultListableBeanFactory beanFactory =(DefaultListableBeanFactory) ac.getBeanFactory();
						Iterator<String> beanNames = beanFactory.getBeanNamesIterator();
						String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
						while(beanNames.hasNext()) {
							String bean = beanNames.next();
							System.out.println(bean);
						}
						System.out.println("------------");
						System.out.println("------------");
						for (int i = 0; i < beanDefinitionNames.length; i++) {
							System.out.println(beanDefinitionNames[i]);
						}
						
//						AutowireCapableBeanFactory beanFactory = ac.getAutowireCapableBeanFactory();
//						beanFactory.autowireBean(obj);
//						beanFactory.initializeBean(obj, "config");
						
						
						
					} else if(event.getType().equals(EventType.NodeDeleted )) {
						// 节点被删掉之后触发这个监听
						System.out.println("节点数据被删除");
					}
				}catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		
		// 从配置中心里面获取数据，本地没有这一份数据库的连接数据
		byte[] data = zkClient.getData(zk.getNodePath(), true, null);
		// 数据格式转换，这里不知道为什么保存之后前面有一点乱码
		String configStr = new String(data);
		configStr = configStr.substring(configStr.indexOf("{"), configStr.lastIndexOf("}") + 1);
		System.out.println("获取到的节点信息：" + configStr);
		// 解析数据，初始化数据配置的对象
		ObjectMapper objectMapper = new ObjectMapper();
		config = objectMapper.readValue(configStr, Config.class);
			
		return config;
	}*/
}
